package org.komarichin.jdo.service;

import org.komarichin.beans.IRole;
import org.komarichin.beans.IUser;
import org.komarichin.beans.dao.IRoleDAO;
import org.komarichin.beans.dao.IUserDAO;
import org.komarichin.beans.service.IUserService;
import org.komarichin.struts2.beans.models.UserRoleModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.providers.encoding.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

/**
 * User: Michael Komarichin
 * Date: 05.10.2009
 * Time: 11:15:10
 */
@Service
public class
        UserService implements IUserService {
    @Autowired
    protected IUserDAO userDAO;
    @Autowired
    protected IRoleDAO roleDAO;
    @Autowired
    protected PasswordEncoder passwordEncoder;

    @Override
    public IUser login(String login, String password) {
        return userDAO.login(login, passwordEncoder.encodePassword(password, null));
    }

    @Override
    public IRole getRoleById(Long id) {
        return roleDAO.getRoleById(id);
    }

    @Override
    public IUser enroll(String login, String password, String hint) {
        IRole role = roleDAO.getRoleByName(USER_ROLE_NAME);
        if (role == null) {
            role = roleDAO.newInstanceRole(null, USER_ROLE_NAME, Long.MAX_VALUE);
            role = roleDAO.save(role);
        }
        IUser user = userDAO.newInstanceUser(null, login, passwordEncoder.encodePassword(password, null), hint);
        user.setRole(role.getId());
        return userDAO.save(user);
    }

    @Override
    public List<IUser> getAllowUsers(Long permission) {
        return new ArrayList<IUser>(userDAO.getAllowUsers(permission));
    }

    @Override
    public List<IRole> getAllowRoles(Long permission) {
        return new ArrayList<IRole>(roleDAO.getAllowRoles(permission));
    }

    @Override
    public IRole createSystemRole() {
        IRole role = roleDAO.getRoleByName(SYSTEM_ROLE_NAME);
        if (role == null) {
            role = roleDAO.newInstanceRole(null, SYSTEM_ROLE_NAME, 0l);
            role = roleDAO.save(role);
        }
        return role;
    }

    public IUser createSystemUser() {
        IUser user = userDAO.findByName(SYSTEM_ROLE_NAME);
        if (user == null) {
            IRole role = createSystemRole();
            user = userDAO.newInstanceUser(null, SYSTEM_ROLE_NAME, passwordEncoder.encodePassword(SYSTEM_ROLE_NAME, null),
                    SYSTEM_ROLE_NAME);
            user.setRole(role.getId());
            userDAO.save(user);
        }
        return user;
    }

    @Override
    public IUser findByName(String login) {
        return userDAO.findByName(login);
    }

    @Override
    public void updateUser(IUser user) {
        userDAO.update(user);
    }

    @Override
    public boolean isUserExists(String login) {
        return findByName(login) != null;
    }

    @Override
    public List<IUser> getUsers() {
        return new ArrayList<IUser>(userDAO.getAll());
    }

    @Override
    public List<IRole> getRoles() {
        return new ArrayList<IRole>(roleDAO.getAll());
    }

    @Override
    public IRole getUserRole(IUser user) {
        return userDAO.getUserRole(user);
    }

    public Collection<UserRoleModel> getUserRole(Long permission){
        Collection<IUser> users = userDAO.getAllowUsers(permission);
        Collection<UserRoleModel> models = new HashSet<UserRoleModel>();
        for(IUser user : users){
            UserRoleModel model = new UserRoleModel();
            model.setId(user.getId());
            model.setLogin(user.getLogin());
            IRole role = userDAO.getUserRole(user);
            model.setRoleName(role.getName());
            model.setRolePermission(role.getPermission());
            models.add(model);
        }
        return models;
    }

    @Override
    public void remove(IUser user) {
        userDAO.remove(user);
    }

    @Override
    public void update(IUser user) {
         userDAO.update(user);
    }

    @Override
    public void remove(IRole role) {
        roleDAO.remove(role);
    }

    @Override
    public void update(IRole role) {
        roleDAO.update(role);
    }
}
